/**
 * @(#)com.tansun.easycare.rule.excel.service.impl.SingleTbIndexExcelServiceImpl.java Copyright (c)
 * 2017 天阳宏业科技股份有限公司
 */
package com.tansun.easycare.rule.excel.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.tansun.easycare.rule.datamodel.dao.RuleDatasetDao;
import com.tansun.easycare.rule.datamodel.entity.RuleDataDomain;
import com.tansun.easycare.rule.datamodel.entity.RuleDataparams;
import com.tansun.easycare.rule.datamodel.entity.RuleDataset;
import com.tansun.easycare.rule.excel.entity.decision.DecisionExcelEntity;
import com.tansun.easycare.rule.excel.service.SingleTbIndexExcelService;
import com.tansun.easycare.rule.excel.utils.BeanUtil;
import com.tansun.easycare.rule.excel.utils.ExcelErrorMsg;
import com.tansun.easycare.rule.excel.utils.ExcelUitl;
import com.tansun.easycare.rule.excel.utils.ParamsUtil;
import com.tansun.easycare.rule.referencedata.dao.RuleReferenceDataDao;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.table.dao.RuleDecisiontableDetailDao;
import com.tansun.easycare.rule.table.entity.RuleDecisiontableDetail;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexEntity;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexItem;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexRow;
import com.tansun.easycare.rule.table.singletblindex.service.SingleTblIndexService;
import com.tansun.rule.common.RuleModelTypeEnum;

/**
 * 一维表索引Excel服务实现
 * @author zengdong
 * @version 1.0  2017年5月31日
 * @modified zengdong  2017年5月31日  <创建>
 */
@Service
public class SingleTbIndexExcelServiceImpl implements SingleTbIndexExcelService {

    @Autowired
    private RuleManageService ruleManageService;

    @Autowired
    private RuleDecisiontableDetailDao decisiontableDetailDao;

    @Autowired
    private RuleReferenceDataDao ruleReferenceDataDao;

    @Autowired
    private SingleTblIndexService singleTbIndex;
    
    @Autowired
    private RuleDatasetDao RuleDatasetDao;

    @Autowired
    private ParamsUtil paramsUtil;


    @Override
    public List<DecisionExcelEntity> getDetailByManageId(String id) {
        List<DecisionExcelEntity> list = new ArrayList<DecisionExcelEntity>();
        RuleManage searchManage = new RuleManage();
        searchManage.setId(id);
        //获取规则管理对象
        RuleManage manage = ruleManageService.get(searchManage);
        if (manage != null) {
            DecisionExcelEntity decisiontable = new DecisionExcelEntity();
            BeanUtil.copyProperties(manage, decisiontable);
            RuleDecisiontableDetail entity = new RuleDecisiontableDetail();
            entity.setManageId(manage.getId());
            entity.setVersion(manage.getVersion());
            //获取规则表内容
            List<RuleDecisiontableDetail> decisiontableList = decisiontableDetailDao.findList(entity);
            if (decisiontableList != null && decisiontableList.size() > 0) {
                decisiontable.setDetailList(decisiontableList);
            }
            list.add(decisiontable);

            RuleReferenceData referenceData = new RuleReferenceData();
            referenceData.setManageId(manage.getId());
            referenceData.setVersion(manage.getVersion());
            Page<RuleReferenceData> page = new Page<RuleReferenceData>();
            page.setOrderBy("seq");
            referenceData.setPage(page);
            //获取规则表参数
            List<RuleReferenceData> refenceDataList = ruleReferenceDataDao.findList(referenceData);
            if (refenceDataList != null && refenceDataList.size() > 0) {
                decisiontable.setReferenList(refenceDataList);
            }
        }
        return list;
    }

    @Override
    public ExcelErrorMsg verifyDecisionTable(List<DecisionExcelEntity> decisionTableList) {
        ExcelErrorMsg msg = new ExcelErrorMsg();
        if (decisionTableList != null && decisionTableList.size() > 0) {
            DecisionExcelEntity entity = decisionTableList.get(0);
            //校验ruleManage的标题
            if (StringUtils.isEmpty(entity.getName())) {
                msg.addErrorMsg("决策表标题不能为空");
            }

            Map<String, RuleDataparams> paramsMap = new HashMap<String, RuleDataparams>();
            Map<String, RuleDataset> datasetMap = new HashMap<String, RuleDataset>();
            Map<String, List<RuleDataDomain>> domainMap = new HashMap<String, List<RuleDataDomain>>();
            //校验参数名
            List<RuleReferenceData> referenceDataList = entity.getReferenList();
            if (referenceDataList != null && referenceDataList.size() > 0) {
                Set<String> referenceSet = new HashSet<String>();
                //判断参数的合法性
                for (int i = 0; i < referenceDataList.size(); i++) {
                    RuleReferenceData reference = referenceDataList.get(i);
                    int rowNum = 2;
                    int colNum = "in".equals(reference.getContentType()) ? i : i + 1;
                    if (StringUtils.isEmpty(reference.getNamecn())) {
                        msg.addErrorMsg("第" + rowNum + "行的第" + colNum + "列参数为空");
                        continue;
                    }
                    RuleDataparams params = new RuleDataparams();
                    params.setProjectcode(entity.getProjectCode());
                    if(reference.getNamecn().indexOf(".")>-1) {
                        params.setChzn(reference.getNamecn().split("\\.")[1]);
                        //获取变量的datasetId
                        RuleDataset dataset = new RuleDataset();
                        dataset.setProjectcode(entity.getProjectCode());
                        dataset.setChzn(reference.getNamecn().split("\\.")[0]);
                        List<RuleDataset> datasetList = RuleDatasetDao.findDatasetList(dataset);
                        if(datasetList.size()>0) {
                            String datasetId=datasetList.get(0).getId();
                            params.setDatasetId(datasetId);
                        }else {
                            msg.addErrorMsg("第" + rowNum + "行的第" + colNum + "列的前缀类名不存在，请确定是否存在该数据模型！");
                        }
                    }else {
                        params.setChzn(reference.getNamecn());
                    }
                    List<RuleDataparams> list = ParamsUtil.paramsDao.findChznList(params);
                    if (list == null || list.size()==0) {
                        msg.addErrorMsg("第" + rowNum + "行的第" + colNum + "列参数不存在，请确定数据模型中存在此参数");
                    } else if (list.size() > 1) {
                        msg.addErrorMsg("第" + rowNum + "行的第" + colNum + "列参数存在多个，请以‘类名.参数名’的形式添加类名前缀! 以便能获取到正确的参数！");
                    } else {
                        RuleDataparams p = list.get(0);
                        paramsMap.put(i + "", p);
//						RuleDataset set = new RuleDataset();
//						set.setId(p.getDatasetId());
//						List<RuleDataset> datasets = ParamsUtil.datasetDao.findList(set);
                        RuleDataset ds = ParamsUtil.datasetDao.get(p.getDatasetId());
                        if (ds != null) {
                            datasetMap.put(i + "", ds);
                        }
                        if (StringUtils.isNotBlank(p.getDomain()) && !p.getDomain().startsWith("[") && !p.getDomain().startsWith("(")) {
                            RuleDataDomain domain = new RuleDataDomain();
                            domain.setDomainId(p.getDomain());
                            List<RuleDataDomain> domainList = ParamsUtil.domainDao.findList(domain);
                            if (domainList != null && domainList.size() > 0) {
                                List<RuleDataDomain> strList = new ArrayList<RuleDataDomain>();
                                for (RuleDataDomain d : domainList) {
                                    strList.add(d);
                                }
                                domainMap.put(i + "", strList);
                            }
                        }

                    }
                    if(referenceSet.contains(reference.getNamecn())) {
                    	System.out.println(reference.getNamecn());
                    }
                    referenceSet.add(reference.getNamecn());
                }
                if (referenceSet.size() != referenceDataList.size()) {
                    msg.addErrorMsg("参数类型存在重复");
                }
            }

            //校验参数值
            List<RuleDecisiontableDetail> detailList = entity.getDetailList();
            List<RuleDecisiontableDetail> replaceList = new ArrayList<RuleDecisiontableDetail>();
            String errorMsg = "";
            if (detailList != null && detailList.size() > 0 && !msg.isExistsErrorMsg()) {
                for (RuleDecisiontableDetail detail : detailList) {
                    RuleDataparams params = null;
                    RuleDataset set = null;
                    String num = "0";
                    int row = 0;
                    int col = 0;
                    row = 3 + detail.getRowNo();
                    col = "in".equals(detail.getContentType()) ? detail.getColumnNo() + 1 : detail.getColumnNo() + 2;
                    num = detail.getColumnNo() + "";
                    params = paramsMap.get(num);
                    if(params==null) {
                    	System.out.println("=====");
                    }
                    set = datasetMap.get(num);
                    if("其他".equals(detail.getControlValue())){
                        params.setType("text");
                        params.setChzn("");
                        params.setName("");
                    }
                    errorMsg = ExcelUitl.verificationValue(detail.getControlValue(), params, detail.getContentType(), domainMap.get(num));
                    if (StringUtils.isNotBlank(params.getDomain()) && !params.getDomain().startsWith("[") && !params.getDomain().startsWith("(")) {
                        params.setType("EMUN");
                    }
                    if (StringUtils.isNotBlank(errorMsg)) {
                        msg.addErrorMsg("第" + row + "行的第" + col + "列的" + errorMsg);
                    } else {
                        replaceList.add(replaceDetail(detail, params, set, detail.getContentType(), domainMap.get(num)));
                    }
                }

            }
            if (StringUtils.isNotBlank(errorMsg)) {
                msg.addErrorMsg(errorMsg);
            } else {
                entity.setDetailList(replaceList);
            }
        }
        return msg;
    }

    /**
     * 转换
     * @param controlValue
     * @param params
     * @return
     */
    private RuleDecisiontableDetail replaceDetail(RuleDecisiontableDetail detail, RuleDataparams params, RuleDataset set, String contentType, List<RuleDataDomain>... list) {
        detail.setClassName(set.getName());
        detail.setContentType(contentType);
        detail.setDataType(params.getType());
        detail.setDefaultValue(params.getDefaultValue());
        detail.setDomain(params.getDomain());
        detail.setIsDerives(params.getIsDerives());
        detail.setNamecn(params.getChzn());
        detail.setNameen(params.getName());
        detail.setCollection(params.getCollection());
        detail.setPattern(StringUtils.isEmpty(params.getPattern()) ? "" : params.getPattern());
        if ("BOOLEAN".equals(params.getType().toUpperCase())) {
            if ("是".equals(detail.getControlValue())) {
                detail.setControlValue("1");
            } else if ("否".equals(detail.getControlValue())) {
                detail.setControlValue("0");
            }
        } else if ("DATE".equals(params.getType().toUpperCase()) || "LONG".equals(params.getType().toUpperCase()) || "DOUBLE".equals(params.getType().toUpperCase())) {
            if ("in".equals(contentType)) {  
                String[] valArg = ExcelUitl.parseControlValue(detail.getControlValue());
                if (valArg != null) {
                    if("LONG".equals(params.getType().toUpperCase()) || "DOUBLE".equals(params.getType().toUpperCase())) {
                        if("@".equals(valArg[0])) {
                            detail.setLowerOpt("==");
                        }else if("#".equals(valArg[0])) {
                            detail.setLowerOpt("!=");
                        }else {
                            detail.setLowerOpt(valArg[0]);
                        }
                    }else {
                        detail.setLowerOpt(valArg[0]);
                    }
                    detail.setControlValue(valArg[1]);
                    detail.setUpperOpt(valArg[2]);
                }
            }
        } else if ("EMUN".equals(params.getType())) {
            StringBuilder sb = new StringBuilder();
            if ("in".equals(contentType)) {
                if (list != null && list.length > 0) {
                    List<RuleDataDomain> domainList = list[0];
                    String[] str = detail.getControlValue().split(",|，");
                    if (str != null && str.length > 0) {
                        for (String s : str) {
                            for (RuleDataDomain domain : domainList) {
                                if (domain.getName().toLowerCase().equals(s.toLowerCase())) {
                                    sb.append(",\"" + domain.getDomainValue() + "\"");
                                }
                            }
                        }
                    }
                }
                if (StringUtils.isNotEmpty(sb.toString())) {
                    detail.setControlValue("[" + sb.toString().substring(1) + "]");
                }
            } else {
                if (list != null && list.length > 0) {
                    List<RuleDataDomain> domainList = list[0];
                    String[] str = detail.getControlValue().split(",|，");
                    if (str != null && str.length > 0) {
                        for (RuleDataDomain domain : domainList) {
                            if (domain.getName().toLowerCase().equals(str[0].toLowerCase())) {
                                sb.append(domain.getDomainValue());
                                break;
                            }
                        }
                    }
                }
                if (StringUtils.isNotEmpty(sb.toString())) {
                    detail.setControlValue(sb.toString());
                }
            }
        }else if ("String".equals(params.getType())) {
            if ("in".equals(contentType)) {
                String[] valArg = (detail.getControlValue()).split("=");
                if(valArg!=null) {
                    if("!".equals(valArg[0])) {
                        detail.setLowerOpt("!=");
                        detail.setControlValue(valArg[1]); 
                    } 
                }
            }
        }
        return detail;
    }

    @Override
    public void saveExcelInfoToDb(List<DecisionExcelEntity> decisionTableList,String rankRelationId) throws Exception {
        if (decisionTableList != null && decisionTableList.size() > 0) {
            DecisionExcelEntity excelEntity = decisionTableList.get(0);
            SingleTblIndexEntity entity = new SingleTblIndexEntity();
            //添加manage
            RuleManage manage = new RuleManage();
            BeanUtil.copyProperties(excelEntity, manage);
            manage.setRankRelationId(rankRelationId);
            ruleManageService.checkImport(manage, RuleModelTypeEnum.SingleTblIndex.getCode());
            entity.setIndexModel(manage);

            //添加SingleTblIndexRow
            List<SingleTblIndexRow> dtList = new ArrayList<SingleTblIndexRow>();
            int i = 0;
            SingleTblIndexRow row = new SingleTblIndexRow();
            List<SingleTblIndexItem> rowItems = new ArrayList<SingleTblIndexItem>();
            for (RuleDecisiontableDetail detail : excelEntity.getDetailList()) {
                if("BOOLEAN".equals(detail.getDataType().toUpperCase())){
                    if("1".equals(detail.getControlValue())){
                        detail.setControlValue("true");
                    }else{
                        detail.setControlValue("false");
                    }
                }
                if (detail.getRowNo() == i) {
                    SingleTblIndexItem item = new SingleTblIndexItem();
                    item.setClassName(detail.getClassName());
                    item.setContentType(detail.getContentType());
                    item.setLowerOpt(detail.getLowerOpt());
                    item.setControlValue(detail.getControlValue());
                    item.setUpperOpt(detail.getUpperOpt());
                    item.setDataType("EMUN".equals(detail.getDataType().toUpperCase()) ? "String" : detail.getDataType());
                    item.setDefaultValue(detail.getDefaultValue());
                    item.setDomain(detail.getDomain());
                    item.setIsDerives(detail.getIsDerives());
                    item.setNameCN(detail.getNamecn());
                    item.setNameEN(detail.getNameen());
                    item.setPosition(detail.getPosition());
                    item.setPattern(detail.getPattern());
                    item.setCollection(detail.getCollection());
                    rowItems.add(item);
                } else {
                    row.setSingleTblRow(rowItems);
                    dtList.add(row);
                    i = detail.getRowNo();
                    row = new SingleTblIndexRow();
                    rowItems = new ArrayList<SingleTblIndexItem>();
                    SingleTblIndexItem item = new SingleTblIndexItem();
                    item.setClassName(detail.getClassName());
                    item.setContentType(detail.getContentType());
                    item.setLowerOpt(detail.getLowerOpt());
                    item.setControlValue(detail.getControlValue());
                    item.setUpperOpt(detail.getUpperOpt());
                    item.setDataType("EMUN".equals(detail.getDataType().toUpperCase()) ? "String" : detail.getDataType());
                    item.setDefaultValue(detail.getDefaultValue());
                    item.setDomain(detail.getDomain());
                    item.setIsDerives(detail.getIsDerives());
                    item.setNameCN(detail.getNamecn());
                    item.setNameEN(detail.getNameen());
                    item.setPosition(detail.getPosition());
                    item.setPattern(detail.getPattern());
                    item.setCollection(detail.getCollection());
                    rowItems.add(item);
                }
            }
            row.setSingleTblRow(rowItems);
            dtList.add(row);

            entity.setSingleTblIndexList(dtList);
            singleTbIndex.saveOrUpdate(entity);
        }
    }

}
